package cs2340.spring13.team3.wheresmystuff.views;

import java.io.IOException;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import cs2340.spring13.team3.wheresmystuff.R;
import cs2340.spring13.team3.wheresmystuff.presenters.LoginManager;

/**
 * @author I Stainbrook, R Keane This class serves as the view for user login
 *         and registration, and is the first view the user is presented with
 *         upon opening the application.
 */

public class LoginActivity extends Activity implements ILoginView {

	private static final int CREATE_ACCOUNT_CALL = 100;

	/**
	 * Keep track of the login task to ensure we can cancel it if requested.
	 */
	private UserLoginTask mAuthTask = null;
	boolean registered;

	// Values for email and password at the time of the login attempt.
	private String mEmail;
	private String mPassword;

	// The class that manages our login information
	private LoginManager loginManager;

	private TextView mLoginStatusMessageView;
	private EditText mEmailField, mPasswordField;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_login);
		loginManager = LoginManager.getInstance();
		registered = false;

		findViewById(R.id.login_status);
		mLoginStatusMessageView = (TextView) findViewById(R.id.login_status_message);

		mEmailField = (EditText) findViewById(R.id.emailField);
		mPasswordField = (EditText) findViewById(R.id.passwordField);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.login, menu);
		return true;
	}

	/**
	 * notifies the screen when a sub-activity completes, and performs the
	 * appropriate actions
	 * 
	 * @param source
	 *            The button from which the click originates
	 */
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == CREATE_ACCOUNT_CALL) {
			String s;
			getEmailField().setText(
					(s = (String) data.getExtras().get("email")) == null ? ""
							: s);
			getPasswordField().setText(
					s = (String) data.getExtras().get("password") == null ? ""
							: s);
			AlertDialog alertDialog = new AlertDialog.Builder(this).create();
			alertDialog.setTitle("Account Creation Successful");
			alertDialog.setMessage("Current user: "
					+ loginManager.getUser().getEmail());
			alertDialog.show();
			alertDialog.setOnDismissListener(new OnDismissListener() {
				public void onDismiss(DialogInterface arg0) {
					afterLogIn();
				}
			});
		}

	}

	/**
	 * Uses a simple AlertDialog to display a message to the end user regarding
	 * the login process
	 * 
	 * @param message
	 *            The message to display
	 */

	@Override
	public void displayLoginMessage(String title, String message) {
		AlertDialog alertDialog = new AlertDialog.Builder(this).create();
		if (title != null && !TextUtils.isEmpty(title))
			alertDialog.setTitle(title);
		alertDialog.setMessage(message);
		alertDialog.show();
	}

	/**
	 * Returns the text field used to input an email address
	 * 
	 * @return The email text field
	 */

	private EditText getEmailField() {
		return (EditText) findViewById(R.id.emailField);
	}

	/**
	 * Returns the text field used to input a password
	 * 
	 * @return The password text field
	 */

	private EditText getPasswordField() {
		return (EditText) findViewById(R.id.passwordField);
	}

	// ****************

	/**
	 * Check the validity of the user-inputed email.
	 * 
	 * @param email
	 *            string to validate
	 * @return whether or not the email is valid according to our incorrect
	 *         regex
	 */
	public boolean checkInvalidEmail(String email) {
		mEmailField.setError(null);
		if (TextUtils.isEmpty(email)) {
			mEmailField.setError("Field is required");
			return true;
		} else if (!email.matches("[a-zA-Z_0-9.]+@[a-zA-Z_0-9.]+.[a-zA-Z]{3}")) {
			mEmailField.setError("Invalid email");
			return true;
		}
		return false;
	}

	/**
	 * Check the validity of the user-inputed password
	 * 
	 * @param password
	 *            string to check
	 * @return whether or not the password is valid (length > 3 characters)
	 */
	public boolean checkInvalidPassword(String password) {
		mPasswordField.setError(null);
		if (TextUtils.isEmpty(password)) {
			mPasswordField.setError("Field is required");
			return true;
		} else if (password.length() < 4) {
			mPasswordField.setError("Password too short");
			return true;
		}
		return false;
	}

	// **************

	private boolean checkInvalidEmailPassword() {
		return checkInvalidEmail(mEmail) || checkInvalidPassword(mPassword);
	}

	/**
	 * Uses the LoginManager (presenter) to attempt a login with the credentials
	 * in the text fields when the corresponding button is clicked
	 * 
	 * @param source
	 *            The button from which the click originates
	 */

	public void onLoginClick(View source) {
		// myLoginManager.attemptLogin(getEmailField().getText().toString(),
		// getPasswordField().getText().toString());
		if (mAuthTask != null) {
			return;
		}

		// Store values at the time of the register attempt.
		mEmail = getEmailField().getText().toString();
		mPassword = getPasswordField().getText().toString();

		boolean cancel = checkInvalidEmailPassword();

		if (!cancel) {
			// mLoginStatusMessageView.setText(R.string.login_progress_signing_in);
			mLoginStatusMessageView.setText(R.string.login_progress_signing_in);
			// showProgress(true);
			mAuthTask = new UserLoginTask(this, mEmail, mPassword);
			mAuthTask.execute((Void) null);
		}

	}

	/**
	 * Shows the progress UI and hides the login form.
	 */
	/*
	 * @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) private void
	 * showProgress(final boolean show) { // On Honeycomb MR2 we have the
	 * ViewPropertyAnimator APIs, which allow // for very easy animations. If
	 * available, use these APIs to fade-in // the progress spinner. if
	 * (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { int
	 * shortAnimTime = getResources().getInteger(
	 * android.R.integer.config_shortAnimTime);
	 * 
	 * mLoginStatusView.setVisibility(View.VISIBLE);
	 * mLoginStatusView.animate().setDuration(shortAnimTime) .alpha(show ? 1 :
	 * 0) .setListener(new AnimatorListenerAdapter() {
	 * 
	 * @Override public void onAnimationEnd(Animator animation) {
	 * mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE); } });
	 * 
	 * mLoginFormView.setVisibility(View.VISIBLE);
	 * mLoginFormView.animate().setDuration(shortAnimTime) .alpha(show ? 0 : 1)
	 * .setListener(new AnimatorListenerAdapter() {
	 * 
	 * @Override public void onAnimationEnd(Animator animation) {
	 * mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); } }); }
	 * else { // The ViewPropertyAnimator APIs are not available, so simply show
	 * // and hide the relevant UI components.
	 * mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE);
	 * mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); } }
	 */

	/**
	 * Method called after all successful log-ins
	 */
	private void afterLogIn() {
		advance();
	}

	/**
	 * Uses the LoginManager (presenter) to attempt to register a new user with
	 * the credentials in the text fields when the corresponding button is
	 * clicked
	 * 
	 * @param source
	 *            The button from which the click originates
	 */

	public void onRegisterClick(View source) {
		if (mAuthTask != null || registered == true) {
			return;
		}
		// Reset errors.
		getEmailField().setError(null);
		getPasswordField().setError(null);

		// start new Activity
		Intent i = new Intent(LoginActivity.this, CreateAccountActivity.class);
		startActivityForResult(i, CREATE_ACCOUNT_CALL);
	}

	/**
	 * Represents an asynchronous login/registration task used to authenticate
	 * the user.
	 */
	public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
		@SuppressWarnings("unused")
		private Activity activity;
		private String email, password;

		public UserLoginTask(Activity applicationActivity, String email,
				String pass) {
			this.activity = applicationActivity;
			this.email = email;
			this.password = pass;
		}

		@Override
		protected Boolean doInBackground(Void... params) {
			try {
				return loginManager.attemptLogin(this.email, this.password);
			} catch (IOException e) {
				e.printStackTrace();
				return false;
			}
		}

		@Override
		protected void onPostExecute(final Boolean success) {
			mAuthTask = null;
			if (success) {
				afterLogIn();
			} else {
				displayLoginMessage("Login Failed", loginManager.getError());
			}
		}

		@Override
		protected void onCancelled() {
			mAuthTask = null;
		}
	}

	public void advance() {
		Intent intent = new Intent(this, ViewItemListActivity.class);
		startActivity(intent);
		finish();
	}

}
